import * as vscode from 'vscode';
import { logger } from "./logger";
import { spawn } from "child_process";

export function prebuildDownload(args: any[], withDownloadSdk: boolean) {
    if (args.length === 0) {
        vscode.window.showErrorMessage('No args provided, please see the log for more information');
        logger.errorWithStack('No args provided');
        return;
    }

    const uri = args[0] as vscode.Uri;
    if (!uri || typeof uri.fsPath !== 'string') {
        vscode.window.showErrorMessage('Invalid URI provided, , please see the log for more information');
        logger.errorWithStack('Invalid URI provided');
        return;
    }

    const path = uri.fsPath;
    logger.info(`bundle.json's path is : ${path}`);
    const pathParts = path.split(/[/\\]/);
    const parentFolderName = pathParts.length >= 2 ? pathParts.slice(-2, -1)[0] : '';

    if (!parentFolderName) {
        vscode.window.showErrorMessage('Could not extract parent folder name from path, please see the log for more information');
        logger.errorWithStack('Could not extract parent folder name from path');
        return;
    }
    logger.info(`parentFolderName is : ${parentFolderName}`);


    const cancellationTokenSource = new vscode.CancellationTokenSource();
    
    vscode.window.withProgress({
        location: vscode.ProgressLocation.Notification,
        title: `[${parentFolderName}]: Begin to Prebuild Download...`,
        cancellable: true
    },
    async (progress, token) => {
        // Execute ls command
        const dirPath = path.substring(0, path.lastIndexOf('/'));
        
        // Find the root directory containing .repo folder
        let repoRootPath = dirPath;
        let foundRepoDir = false;
        
        try {
            while (repoRootPath && repoRootPath !== '/') {
                const potentialRepoDir = `${repoRootPath}/.repo`;
                const fs = require('fs');
                
                if (fs.existsSync(potentialRepoDir) && fs.statSync(potentialRepoDir).isDirectory()) {
                    foundRepoDir = true;
                    logger.info(`Found .repo directory at: ${repoRootPath}`);
                    break;
                }
                
                // Move up one directory
                repoRootPath = repoRootPath.substring(0, repoRootPath.lastIndexOf('/'));
            }
            
            if (!foundRepoDir) {
                logger.error('Could not find .repo directory in any parent folder');
                vscode.window.showErrorMessage(`[${parentFolderName}]: Could not find .repo directory`);
                return false;
            }
        } catch (error) {
            logger.errorWithStack('Error while searching for .repo directory');
            vscode.window.showErrorMessage(`[${parentFolderName}]: Error while searching for .repo directory`);
            return false;
        }
        
        try {
            // 执行命令
            const result = await executeAndLogCommand(withDownloadSdk, dirPath, parentFolderName, token, repoRootPath);

            if (result && result.status === 'success') {
                // 成功时的操作
                vscode.window.showInformationMessage(`[${parentFolderName}]: Prebuild download Success`);
                return true;
            } else {
                vscode.window.showErrorMessage(`[${parentFolderName}]: Prebuild download failed, ${result?.message}`);
                return false;
            }
        } catch (error) {
            // 发生错误时显示错误消息
            if (error instanceof Error) {
                logger.errorWithStack(error.message);
            } else {
                logger.errorWithStack("Prebuild download failed");
            }
            vscode.window.showErrorMessage(`[${parentFolderName}]: Prebuild download failed, Please check the log for more information`);     
            return false; // 表示操作失败
        }
    });
}

async function executeAndLogCommand(withDownloadSdk: boolean, dirPath: string, parentFolderName: string, token?: vscode.CancellationToken, repoRootPath?: string) {
    try {
        logger.show();
        logger.info(`Begin to prebuild download, dirPath is ${dirPath}, parentFolderName is ${parentFolderName}`);
        
        let commandStr = `bash ./build/prebuilts_config.sh`;

        if (withDownloadSdk) {
            commandStr += ` --download-sdk`;
        }

        logger.info(`command is ${commandStr}`);

        // 获取命令执行的工作目录（文件所在目录）
        const workingDir = repoRootPath;
        
        // 将命令字符串分解为命令和参数
        const parts = commandStr.split(' ');
        const command = parts[0];
        const args = parts.slice(1);
        
        const process = spawn(command, args, { 
            cwd: workingDir 
        });

        // 实时处理标准输出
        process.stdout.on('data', (data) => {
            const output = data.toString().trim();
            if (output) {
                output.split('\n').forEach((line: string) => {
                    if (line.trim()) {
                        logger.append(`  ${line}`);
                    }
                });
            }
        });
        
        // 实时处理标准错误
        process.stderr.on('data', (data) => {
            const output = data.toString().trim();
            if (output) {
                output.split('\n').forEach((line: string) => {
                    if (line.trim()) {
                        logger.append(`  ${line}`);
                    }
                });
            }
        });
        
        return new Promise<{ status: string; message?: string }>((resolve, reject) => {
            // 保存对取消状态的引用
            let isCancelled = false;
            
            if (token) {
                token.onCancellationRequested(() => {
                    isCancelled = true;
                    process.kill();
                    logger.info(`Prebuild download cancelled by user`);
                    resolve({ status: 'failed', message: 'Prebuild download cancelled by user' });
                });
            }
            
            process.on('close', (code) => {
                // 如果已经因为取消而解析了，就不要重复解析
                if (isCancelled) {
                    return;
                }
                
                if (code === 0) {
                    resolve({ status: 'success' });
                } else {
                    const errorMsg = `命令 ${commandStr} 执行失败，退出码: ${code}`;
                    logger.errorWithStack(errorMsg);
                    reject({ status: 'failed', message: "please check the log for more information" });
                }
            });
            
            process.on('error', (err) => {
                // 如果已经因为取消而解析了，就不要重复解析
                if (isCancelled) {
                    return;
                }
                
                logger.errorWithStack(`command execution error: ${err.message}`);
                reject({ status: 'failed', message: "please check the log for more information" });
            });
        });
    } catch (error) {
        if (error instanceof Error) {
            logger.errorWithStack(`执行命令时出错: ${error.message}`);
        } else {
            logger.errorWithStack(`执行命令时发生未知错误`);
        }
        return { status: 'failed', message: 'please check the log for more information' };
    }
}